﻿using HCMS.CommonDtos;
using HCMS.Const;
using HCMS.Entities.Manage;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using HCMS.Utils;
using HCMS.Web.Manage.Filter;
using Microsoft.AspNetCore.Mvc;

namespace HCMS.Web.Manage.Controllers.Module.Manage
{
    /// <summary>
    /// 管理 菜单
    /// </summary>
    public class MenuController : ModuleController
    {
        private readonly IMenuAppService menuAppService;
        private readonly IRoleMenuAppService roleMenuAppService;

        public MenuController(
            IMenuAppService menuAppService,
            IRoleMenuAppService roleMenuAppService
            )
        {
            this.menuAppService = menuAppService;
            this.roleMenuAppService = roleMenuAppService;
        }

        #region 列表
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult List()
        {
            return View($"{BasePath}/Manage/Menu/List.cshtml");
        }

        /// <summary>
        /// 列表 Ajax
        /// </summary>
        /// <remarks>
        /// 树结构 数据
        /// </remarks>
        /// <returns></returns>
        [ActionName("List")]
        [HttpPost]
        public async Task<IActionResult> PostList()
        {
            var searchArgs = new SearchArgsDto()
            {
                Status = Request.Form["status"].ToInt(9999),

                SearchName = Request.Form["searchName"].ToString(),
                SearchKey = Request.Form["searchKey"].ToString()
            };

            var pager = new PagerArgsDto()
            {
                IsPager = false
            };

            var result = await menuAppService.ManageList(searchArgs, pager);
            var isSearch = (searchArgs.Status != 9999 || !string.IsNullOrWhiteSpace(searchArgs.SearchKey)) && result.Data.Any();

            // 搜索，直接返回结果
            if (isSearch)
            {
                var obj = result.Data.ToList().Select(a => new
                {
                    id = a.Id,
                    name = a.Name,
                    status = a.Status,
                    createTime = a.CreateTime,
                    createUser = a.CreateUser,
                    updateTime = a.UpdateTime,
                    updateUser = a.UpdateUser,
                    icon = a.Icon,
                    typeId = a.TypeId
                }).ToList();
                return Json(new { code = 0, data = obj, count = result.PagerInfo.RowCount, msg = "ok" });
            }

            // 没有搜索，返回全部数据
            var allTree = await menuAppService.GetAllTree();

            return Json(new { code = 0, data = allTree, msg = "ok" });
        }
        #endregion

        #region 新增、编辑、保存
        /// <summary>
        /// 新增
        /// </summary>
        /// <returns></returns>
        public IActionResult Add()
        {
            var model = new Menu();
            return View($"{BasePath}/Manage/Menu/Edit.cshtml", model);
        }

        /// <summary>
        /// 添加子级
        /// </summary>
        /// <param name="parentId">父级 Id</param>
        /// <returns></returns>
        public async Task<IActionResult> AddChildren(int parentId = 0)
        {
            var controllerName = string.Empty;
            if (parentId > 0)
            {
                var parentInfo = await menuAppService.BaseFirstOrDefaultAsync(t => t.Id == parentId);
                if (parentInfo != null && !string.IsNullOrWhiteSpace(parentInfo.ControllerName))
                {
                    controllerName = parentInfo.ControllerName;
                }
            }

            var model = new Menu()
            {
                ParentId = parentId,
                ControllerName = controllerName
            };
            return View($"{BasePath}/Manage/Menu/Edit.cshtml", model);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> Edit(int id)
        {
            if (id <= 0)
            {
                return Content("参数无效");
            }

            var model = await menuAppService.BaseFirstOrDefaultAsync(t => t.Id == id);
            if (model == null)
            {
                return Content($"没有找到【id：{id}】菜单信息");
            }

            return View($"{BasePath}/Manage/Menu/Edit.cshtml", model);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="menu"></param>
        /// <returns></returns>
        public async Task<IActionResult> Save(Menu menu)
        {
            Menu? result = null;

            // 实体更新公共方法
            Func<Menu, string> entityUpdateCommon = delegate (Menu entity)
            {
                string errorMsg = string.Empty;

                if (!string.IsNullOrWhiteSpace(entity.Icon))
                {
                    var iconArray = entity.Icon.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (iconArray != null && iconArray.Length > 0 && iconArray.Count(t => t == "layui-icon") == 0)
                    {
                        entity.Icon = $"layui-icon {entity.Icon}";
                    }
                }

                // 控制器 + 方法 名称，必须唯一
                if (!string.IsNullOrWhiteSpace(entity.ControllerName) && !string.IsNullOrWhiteSpace(entity.ActionName))
                {
                    var hasRepeat = menuAppService.HasRepeat(entity.Id, entity.ControllerName, entity.ActionName).Result;
                    if (hasRepeat)
                    {
                        errorMsg = string.Format("已经有同名的控制器【{0}】、方法【{1}】，请将方法改成其它名称后，再保存",
                            entity.ControllerName, entity.ActionName);
                    }
                }

                entity = EntityConvertUtil.FieldsNullConvertDefault(entity);

                return errorMsg;
            };

            if (menu == null)
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "参数无效" });
            }
            if (string.IsNullOrWhiteSpace(menu.Name))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写名称" });
            }
            if (string.IsNullOrWhiteSpace(menu.DisplayName))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写显示名称" });
            }

            var parentId = Request.Form["ParentId"].ToInt(-1);
            if (parentId == -1)
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请选择所属上级" });
            }

            var parentPath = (await menuAppService.BaseFirstOrDefaultAsync(t => t.Id == parentId))?.ParentPath;

            if (!string.IsNullOrWhiteSpace(parentPath))
            {
                var pathIdArray = parentPath.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var pathIdList = Array.ConvertAll(pathIdArray, int.Parse).ToList();
                pathIdList.Add(parentId);
                parentPath = string.Join(",", pathIdList);
            }
            else
            {
                parentPath = $"{parentId}";
            }

            var entity = await menuAppService.BaseFirstOrDefaultAsync(t => t.Id == menu.Id);
            if (entity != null)
            {
                if (entity.Id == parentId)
                {
                    throw new UserFriendlyException("不能选择自己作为上级，请重新选择");
                }

                await TryUpdateModelAsync(entity);
                entity.ParentId = parentId;
                entity.ParentPath = parentPath;
                entity.UpdateTime = DateTime.Now;
                entity.UpdateUser = CurrentAdmin.AdminName;
                var commonMsg = entityUpdateCommon(entity);
                if (!string.IsNullOrWhiteSpace(commonMsg))
                {
                    throw new UserFriendlyException(commonMsg);
                }
                result = await menuAppService.BaseUpdateAsync(entity);
            }
            else
            {
                entity = new Menu()
                {
                    CreateTime = DateTime.Now,
                    CreateUser = CurrentAdmin.AdminName,
                    UpdateTime = DateTime.Now,
                    UpdateUser = CurrentAdmin.AdminName,
                    ParentId = parentId,
                    ParentPath = parentPath
                };
                await TryUpdateModelAsync(entity);
                var commonMsg = entityUpdateCommon(entity);
                if (!string.IsNullOrWhiteSpace(commonMsg))
                {
                    throw new UserFriendlyException(commonMsg);
                }
                result = await menuAppService.BaseInsertAsync(entity);
            }

            if (result != null)
            {
                // 刷新【超级管理员】权限缓存
                await roleMenuAppService.RefreshCacheByRoleId(ManageConst.SuperRoleId);

                return Json(new AjaxResultDto() { Message = "处理成功" });
            }
            else
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "处理失败" });
            }
        }
        #endregion

        #region 获取树结构
        /// <summary>
        /// 获取树结构
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> AllTree()
        {
            var result = await menuAppService.GetAllTree(status: 0);
            return Json(result);
        }
        #endregion

        #region 获取管理系统 菜单树
        /// <summary>
        /// 获取管理系统 菜单树
        /// </summary>
        /// <returns></returns>
        [DefaultPermission]
        [HttpGet]
        public async Task<IActionResult> MenuTree()
        {
            var result = await roleMenuAppService.GetManageMenuByRoleId(CurrentAdmin.RoleId);
            return Json(result);
        }
        #endregion
    }
}
